home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
dviware
/
dvitops
/
code.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-25
|
10KB
|
452 lines
#include "dvitops.h"
static char rcsid[] = "$Header: /usr/jjc/dvitops/RCS/code.c,v 1.5 90/08/14 13:07:42 jjc Rel $";
static struct {
char *name;
int width;
int height;
} paper_table[] =
{
"letter", 612, 792,
"lettersmall", 612, 792,
"a4", 595, 842,
"A4", 595, 842,
"a4small", 595, 842,
"legal", 612, 1008,
"b5", 516, 729,
"b4", 729, 1032,
"tabloid", 792, 1224,
"ledger", 1224, 792,
"statement", 396, 612,
"executive", 540, 720,
"a3", 842, 1190,
"a5", 420, 595,
"folio", 612, 936,
"quarto", 610, 780,
"10x17", 720, 1224,
NULL };
#define MAXCOLS 70
static FILE *psfp;
static int cols = 0; /* the number of characters on the current line */
#define NS 200
typedef struct string {
size_t i; /* index into pool */
int n; /* number of characters */
int region;
integer h;
integer v;
struct string *next;
} STRING;
struct rule {
int region;
integer a,b,h,v;
struct rule *next;
} *rule_list = NULL;
static unsigned char *pool = NULL;
static size_t pool_size = 0, pool_used = 0;
STRING *string_list[MAXFONTS]; /* one list of strings for each font */
STRING *free_string_list;
#ifdef PROTO
void ps_string(unsigned char *s, int n);
void print_string_list(STRING *s);
static void print_rule_list(void);
#else
void ps_string();
void print_string_list();
static void print_rule_list();
#endif
static int page_number = 0;
int landscape = FALSE;
int magnification = 0;
void print_string_list(s)
STRING *s;
{
int cc;
integer v;
integer ox = 0, oy = 0; /* current origin */
int r = NO_REGION; /* the current region */
if (s == NULL)
return;
v = s->v + 1; /* use the 'Z' command not the 'X' command */
while (s != NULL) {
if (s->region != r) {
fprintf(psfp, "%% region %d\n", s->region);
if (r != NO_REGION)
fputs("grestore\n", psfp);
if (s->region != NO_REGION) {
fputs("gsave\n", psfp);
do_transform(s->region, &ox, &oy, psfp);
}
else
ox = oy = 0;
r = s->region;
v = s->v + 1; /* use the 'Z' command not the 'X' command */
}
if (s->v == v) {
cols = put_dim((long)(s->h - ox), psfp);
cc = 'X';
}
else {
cols = put_dim((long)(s->h - ox), psfp);
putc(' ', psfp);
cols++;
cols += put_dim((long)(s->v - oy), psfp);
cc = 'Z';
}
v = s->v;
ps_string(pool + s->i, s->n);
putc(cc, psfp);
putc('\n', psfp);
s = s->next;
}
if (r != NO_REGION)
fputs("grestore\n", psfp);
}
void set_string(p, n, f, h, v)
char *p;
int n, f;
integer h, v;
{
STRING *s;
if (!free_string_list) {
int i;
free_string_list = (STRING *)malloc(sizeof(STRING)*NS);
if (free_string_list == NULL)
out_of_memory();
for (i = 0; i < NS - 1; ++i)
free_string_list[i].next = free_string_list + i + 1;
free_string_list[NS - 1].next = NULL;
}
s = free_string_list;
free_string_list = free_string_list->next;
if (pool == NULL || pool_size - pool_used < n) {
if (pool == NULL) {
pool_size = 5000;
pool = (unsigned char *)malloc(pool_size);
pool_used = 0;
}
else {
if (pool_used > SIZE_MAX - n)
message(FATAL_ERROR, "too many characters on the page");
pool_size = pool_used + n;
if (pool_size > SIZE_MAX/2)
pool_size = SIZE_MAX;
else
pool_size <<= 1;
pool = (unsigned char *)realloc((char *)pool, pool_size);
}
if (pool == NULL)
out_of_memory();
}
s->i = pool_used;
memcpy((char *)(pool + pool_used), p, n);
pool_used += n;
s->h = h;
s->v = v;
s->n = n;
s->next = string_list[f];
s->region = current_region;
string_list[f] = s;
}
void set_rule(a, b, h, v)
integer a, b, h, v;
{
struct rule *p;
if (a <= 0 || b <= 0)
return;
p = (struct rule *)malloc(sizeof(struct rule));
if (p == NULL)
out_of_memory();
p->a = a;
p->b = b;
p->h = h;
p->v = v;
p->region = current_region;
p->next = rule_list;
rule_list = p;
}
static void print_rule_list()
{
int r = NO_REGION;
integer ox = 0, oy = 0;
struct rule *p = rule_list;
while (p != NULL) {
struct rule *q = p;
if (p->region != r) {
fprintf(psfp, "%% region %d\n", p->region);
if (r != NO_REGION)
fputs("grestore\n", psfp);
if (p->region != NO_REGION) {
fputs("gsave\n", psfp);
do_transform(p->region, &ox, &oy, psfp);
}
else
ox = oy = 0;
r = p->region;
}
put_dim((long)(p->a), psfp);
putc(' ', psfp);
put_dim((long)(p->b), psfp);
putc(' ', psfp);
put_dim((long)(p->h - ox), psfp);
putc(' ', psfp);
put_dim((long)(p->v - oy), psfp);
fputs(" R\n", psfp);
p = p->next;
free((char *)q);
}
rule_list = NULL;
if (r != NO_REGION)
fputs("grestore\n", psfp);
}
void eop(page)
struct page_info *page;
{
char page_label[100];
int i, j;
char *ptr;
int page_height, page_width;
for (i = 0; paper_table[i].name != NULL; i++)
if (strcmp(paper_table[i].name, page->paper) == 0)
break;
if (paper_table[i].name == NULL) {
page_height = paper_table[0].height;
page_width = paper_table[0].width;
message(ERROR, "unrecognised page type %s", optarg);
}
else {
page_height = paper_table[i].height;
page_width = paper_table[i].width;
}
ptr = page_label;
for (i = 9; page->count[i] == 0 && i > 0; --i)
;
for (j = 0; j < i; ++j) {
sprintf(ptr, "%ld.", (long)(page->count[j]));
ptr += strlen(ptr);
}
sprintf(ptr, "%ld", (long)page->count[i]);
if (!quiet)
fprintf(stderr, "[%s", page_label);
++page_number;
fprintf(psfp, "\n%%%%Page: %s %d\n", page_label, page_number);
fputs("dvitops begin\n", psfp);
fprintf(psfp, "/#copies %d def BP\n", page->copies);
p_form_list(psfp);
if (landscape) {
int n;
fprintf(psfp, "%d landscape\n", page_width);
n = page_height;
page_height = page_width;
page_width = n;
landscape = FALSE;
}
if (magnification > 0) {
page->mag = magnification;
magnification = 0;
}
fprintf(psfp, "%ld ", (long)(page->num));
put_dim((long)(page->den), psfp);
fprintf(psfp, " %d %g %g %d SC\n",
page->mag, page->hoffset, page->voffset, page_height);
p_inline_list(psfp);
p_import_list(psfp, page);
#ifdef TPIC_SUPPORT
p_tpic_list(psfp, page);
#endif
print_rule_list();
for (j = 0; j < MAXFONTS; ++j) {
int emitted = FALSE;
for (i = j; i != EOF; i = same_font(i)) {
STRING *p = NULL;
STRING *q = string_list[i];
STRING *last = q;
if (string_list[i] == NULL)
continue;
/* reverse the string list */
while (q != NULL) {
STRING *temp = q;
q = q->next;
temp->next = p;
p = temp;
}
if (!f_is_blank(i)) {
if (!emitted) {
fputs("BO\n", psfp);
f_emit(i, psfp);
emitted = TRUE;
}
f_set(i, psfp);
print_string_list(p);
}
last->next = free_string_list;
free_string_list = p;
string_list[i] = NULL;
}
if (emitted)
fputs("EO\n", psfp);
}
pool_used = 0;
fputs("\nEP end", psfp);
if (ferror(psfp))
message(FATAL_ERROR, "write error: disk full?");
if (!quiet)
fputs("] ", stderr);
pool_used = 0;
current_region = NO_REGION;
nregions = 0;
}
void trailer()
{
fputs("\n%%Trailer\n", psfp);
if (!quiet)
fputc('\n', stderr);
}
void prologue(fp, npages, is_reverse, paper)
FILE *fp;
int npages, is_reverse;
char *paper;
{
time_t t;
psfp = fp;
(void)time(&t);
fputs("%!PS-Adobe-2.0\n", psfp);
fputs("%%Creator: dvitops\n", psfp);
f_comment(psfp);
fprintf(psfp, "%%%%CreationDate: %s", ctime(&t));
fprintf(psfp, "%%%%DocumentPaperSizes: %s\n", paper);
fprintf(psfp, "%%%%Pages: %d %d\n", npages, (is_reverse ? -1 : 1));
fputs("%%EndComments\n", psfp);
p_special_prologues(psfp);
if (include_file("dvitops.pro", psfp) == EOF)
message(FATAL_ERROR, "can't open dvitops.pro");
fputs("dvitops begin\n", psfp);
f_prologue(psfp);
fputs("end\n", psfp);
fputs("%%EndProlog\n", psfp);
fprintf(psfp, "%%%%BeginSetup\n");
fprintf(psfp, "%%%%PaperSize: %s\n", paper);
fprintf(psfp, "%%%%EndSetup\n");
}
/* we asssume all seven-bit printable ascii characters are representable in the
host character set */
#define ASCII_LEFT_PARENTHESIS 050
#define ASCII_RIGHT_PARENTHESIS 051
#define ASCII_BACKSLASH 0134
void ps_string(s, n)
unsigned char *s;
int n;
{
cols++;
putc('(', psfp);
while (n--) {
unsigned char c = *s++;
if (c == ASCII_LEFT_PARENTHESIS
|| c == ASCII_RIGHT_PARENTHESIS
|| c == ASCII_BACKSLASH) {
if (cols + 2 > MAXCOLS)
cols = 0, fputs("\\\n", psfp);
fputc('\\', psfp); fputc(XCHAR(c), psfp);
cols += 2;
}
else if (c >= 040 && c < 0177) {
if (cols + 1 > MAXCOLS)
cols = 0, fputs("\\\n", psfp);
putc(XCHAR(c), psfp);
cols++;
}
else {
if (cols + 4 > MAXCOLS)
cols = 0, fputs("\\\n", psfp);
fprintf(psfp, "\\%03o", c);
cols += 4;
}
}
putc(')', psfp);
}
static int fixed_point = 4;
#define LONG_DIGITS 10
int put_dim(n, fp)
long n;
FILE *fp;
{
int len;
/* room for a -, LONG_DIGITS digits, a decimal point,
and a terminating '\0' */
char buf[LONG_DIGITS + 3];
char *p = buf + LONG_DIGITS + 2;
int point = 0;
buf[LONG_DIGITS + 2] = '\0';
if (n >= 0) {
do {
*--p = '0' + (n % 10);
n /= 10;
if (++point == fixed_point)
*--p = '.';
} while (n != 0 || point < fixed_point);
}
else { /* n < 0 */
do {
*--p = '0' - (n % 10);
n /= 10;
if (++point == fixed_point)
*--p = '.';
} while (n != 0 || point < fixed_point);
*--p = '-';
}
if (fixed_point > 0) {
char *q;
/* there must be a dot, so this will terminate */
for (q = buf + LONG_DIGITS + 2; q[-1] == '0'; --q)
;
if (q[-1] == '.') {
if (q - 1 == p) {
q[-1] = '0';
q[0] = '\0';
}
else
q[-1] = '\0';
}
else
*q = '\0';
}
len = strlen(p);
fputs(p, fp);
return len;
}
/*
Local Variables:
tab-width: 4
c-indent-level: 4
c-continued-statement-offset: 4
c-brace-offset: -4
c-argdecl-indent: 0
c-label-offset: -4
End:
*/